/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.platform.EstateApplicationFormDTO;
import org.springblade.modules.admin.entity.EstateApplicationElevator;
import org.springblade.modules.admin.entity.EstateApplicationForm;
import org.springblade.modules.admin.mapper.EstateApplicationFormMapper;
import org.springblade.modules.admin.service.IEstateApplicationElevatorService;
import org.springblade.modules.admin.service.IEstateApplicationFormService;
import org.springblade.modules.admin.entity.MaintainMsg;
import org.springblade.modules.admin.enums.MsgTypeEnum;
import org.springblade.modules.admin.service.MaintainMsgService;
import org.springblade.modules.admin.vo.BuildingElevatorSimpleInfoVO;
import org.springblade.modules.admin.vo.CommonSelectVO;
import org.springblade.modules.admin.vo.ElevatorSimpleInfoVO;
import org.springblade.modules.admin.vo.EstateApplicationFormHomePageVO;
import org.springblade.modules.admin.vo.EstateApplicationFormVO;
import org.springblade.modules.admin.vo.platform.ApplicationFormVO;
import org.springblade.modules.admin.vo.platform.FormBuildingInfoVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 物业项目关联申请记录表 服务实现类
 *
 * @author ysq
 * @since 2022-05-27
 */
@Service
@AllArgsConstructor
public class EstateApplicationFormServiceImpl extends BaseServiceImpl<EstateApplicationFormMapper, EstateApplicationForm> implements IEstateApplicationFormService {

	private final IEstateApplicationElevatorService estateApplicationElevatorService;
	private final MaintainMsgService maintainMsgService;

	@Override
	public IPage<EstateApplicationFormVO> selectEstateApplicationFormPage(IPage<EstateApplicationFormVO> page, EstateApplicationFormVO estateApplicationForm) {
		return page.setRecords(baseMapper.selectEstateApplicationFormPage(page, estateApplicationForm));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveForm(EstateApplicationFormVO estateApplicationFormVO) {
		EstateApplicationForm estateApplicationForm = new EstateApplicationForm();
		estateApplicationForm.setSourceType(estateApplicationFormVO.getSourceType());
		estateApplicationForm.setApplicantId(AuthUtil.getUserId());
		estateApplicationForm.setApplicantName(AuthUtil.getNickName());
		estateApplicationForm.setApplicantPhone(AuthUtil.getDetail().getStr("phone"));
		estateApplicationForm.setStatus(0);
		if (this.save(estateApplicationForm)) {
			List<BuildingElevatorSimpleInfoVO> buildingInfos = estateApplicationFormVO.getBuildingInfos();
			if (Func.isEmpty(buildingInfos)) {
				throw new ServiceException("未选择关联的电梯!");
			}

			List<EstateApplicationElevator> applicationElevatorList = new ArrayList<>();
			for (BuildingElevatorSimpleInfoVO buildingInfo : buildingInfos) {
				for (ElevatorSimpleInfoVO elevatorInfo : buildingInfo.getElevatorInfos()) {
					EstateApplicationElevator applicationElevator = new EstateApplicationElevator();
					applicationElevator.setFormId(estateApplicationForm.getId());
					applicationElevator.setBuildingId(buildingInfo.getBuildingId());
					applicationElevator.setBuildingName(buildingInfo.getBuildingName());
					applicationElevator.setElevatorId(elevatorInfo.getElevatorId());
					applicationElevator.setElevatorAddress(elevatorInfo.getElevatorAddress());
					applicationElevator.setDeptId(buildingInfo.getDeptId());
					applicationElevatorList.add(applicationElevator);
				}
			}
			estateApplicationElevatorService.saveBatch(applicationElevatorList);

			// 发送通知
			String projectNames = buildingInfos.stream().map(t -> t.getBuildingName()).collect(Collectors.joining("、"));
			MaintainMsg msg = new MaintainMsg();
			msg.setTitle(String.valueOf(estateApplicationForm.getId()));
			msg.setContent(projectNames);
			msg.setType(MsgTypeEnum.ELEVATOR_RELEVANCE.getId());
			msg.setOtherId(estateApplicationForm.getId());
			msg.setReceiveTenantId(BladeConstant.ADMIN_TENANT_ID);
			msg.setCode("projectCorrelation");
			maintainMsgService.sendMsg(msg);

			return true;
		}

		return false;
	}

	@Override
	public IPage<EstateApplicationFormHomePageVO> selectEstateApplicationFormHomePageVO(IPage<EstateApplicationFormHomePageVO> page, EstateApplicationFormVO estateApplicationForm) {
		return page.setRecords(baseMapper.selectEstateApplicationFormHomePageVO(estateApplicationForm,page));
	}

	@Override
	public IPage<ApplicationFormVO> selectEstateApplicationFormPage(EstateApplicationFormDTO estateApplicationFormDTO) {
		Query query = new Query();
		query.setSize(estateApplicationFormDTO.getSize());
		query.setCurrent(estateApplicationFormDTO.getCurrent());
		IPage<ApplicationFormVO> page = baseMapper.page(Condition.getPage(query), estateApplicationFormDTO);
		List<ApplicationFormVO> records = page.getRecords();
		if (records.size() == 0) {
			return page;
		}
		List<Long> ids = records.stream().map(ApplicationFormVO::getId).collect(Collectors.toList());
		List<EstateApplicationElevator> applicationElevatorList = estateApplicationElevatorService.list(Wrappers.<EstateApplicationElevator>lambdaQuery().in(EstateApplicationElevator::getFormId, ids));
		Map<Long, List<EstateApplicationElevator>> listMap = applicationElevatorList.stream().collect(Collectors.groupingBy(EstateApplicationElevator::getFormId));
		for (ApplicationFormVO applicationFormVO : records) {
			List<EstateApplicationElevator> estateApplicationElevators = listMap.get(applicationFormVO.getId());
			List<String> highlightElevatorNames = new ArrayList<>(16);
			if (estateApplicationFormDTO.getBuildingIds() != null && estateApplicationFormDTO.getBuildingIds().size() > 0) {
				for (Long buildingId : estateApplicationFormDTO.getBuildingIds()) {
					List<EstateApplicationElevator> collect1 = estateApplicationElevators.stream().filter(o -> o.getBuildingId().equals(buildingId)).collect(Collectors.toList());
					List<EstateApplicationElevator> collect2 = estateApplicationElevators.stream().filter(o -> !o.getBuildingId().equals(buildingId)).collect(Collectors.toList());
					List<String> buildingNames0 = new ArrayList<>(16);
					List<String> buildingNames1 = collect1.stream().map(EstateApplicationElevator::getBuildingName).distinct().collect(Collectors.toList());
					List<String> buildingNames2 = collect2.stream().map(EstateApplicationElevator::getBuildingName).distinct().collect(Collectors.toList());
					buildingNames0.addAll(buildingNames1);
					buildingNames0.addAll(buildingNames2);
					applicationFormVO.setBuildingNames(buildingNames0.stream().distinct().collect(Collectors.toList()));
					applicationFormVO.setHighlightBuildingNames(buildingNames1);
				}
			} else {
				List<String> buildingNames = estateApplicationElevators.stream().map(EstateApplicationElevator::getBuildingName).distinct().collect(Collectors.toList());
				applicationFormVO.setBuildingNames(buildingNames);
			}

			final Map<Long, List<EstateApplicationElevator>> listMap1 = estateApplicationElevators.stream().collect(Collectors.groupingBy(EstateApplicationElevator::getBuildingId));
			List<Long> buildingIds = estateApplicationElevators.stream().map(EstateApplicationElevator::getBuildingId).distinct().collect(Collectors.toList());
			applicationFormVO.setBuildingCounts(buildingIds.size());
			int elevatorCounts = 0;
			List<FormBuildingInfoVo> resultList = new ArrayList<>(16);
			for (Long buildingId : buildingIds) {
				FormBuildingInfoVo formBuildingInfoVo = new FormBuildingInfoVo();
				List<EstateApplicationElevator> applicationElevators = listMap1.get(buildingId);
				final String buildingName = applicationElevators.get(0).getBuildingName();
				final List<String> collect = applicationElevators.stream().map(EstateApplicationElevator::getElevatorAddress).collect(Collectors.toList());
				final Map<Long, List<EstateApplicationElevator>> listMap2 = applicationElevators.stream().collect(Collectors.groupingBy(EstateApplicationElevator::getElevatorId));
				final List<Long> collect2 = applicationElevators.stream().map(EstateApplicationElevator::getElevatorId).collect(Collectors.toList());
				elevatorCounts = elevatorCounts + collect.size();
				if (estateApplicationFormDTO.getElevatorIds() != null && estateApplicationFormDTO.getElevatorIds().size() > 0) {
					for (Long elevatorId : estateApplicationFormDTO.getElevatorIds()) {
						if (collect2.contains(elevatorId)) {
							formBuildingInfoVo.setWeight(1);
							highlightElevatorNames.add(listMap2.get(elevatorId).get(0).getElevatorAddress());
						}
					}
				}
				formBuildingInfoVo.setId(buildingId);
				formBuildingInfoVo.setName(buildingName);
				formBuildingInfoVo.setElevatorNames(collect);
				resultList.add(formBuildingInfoVo);
			}
			applicationFormVO.setElevatorCounts(elevatorCounts);
			Collections.sort(resultList);
			applicationFormVO.setBuildingAndElevatorNames(resultList);
			applicationFormVO.setHighlightElevatorNames(highlightElevatorNames);
		}
		return page;
	}

	@Override
	public List<Map<String, Object>> selectName(Long formId) {
		return baseMapper.selectName(formId);
	}

	@Override
	public List<CommonSelectVO> selectElevator(Long formId) {
		return baseMapper.selectElevator(formId);
	}

	@Override
	public List<Map<String, Object>> selectUser() {
		return baseMapper.selectUser();

	}

}
